/**
 * 渲染器不仅可以把虚拟DOM渲染为浏览器平台上的真实DOM，还可以配置为‘通用’的渲染器，渲染到指定的平台上
 * 抽离与浏览器相关的API，使得渲染器的核心实现不依赖浏览器
 */

const vnode = {
  type: "h1",
  children: "hello",
};
const renderer = createRenderer({
  createElement(tag) {
    return document.createElement(tag);
  },
  setElementText(el, text) {
    el.textContent = text;
  },
  insert(el, parent, anchor = null) {
    parent.insertBefore(el, anchor);
  },
});

function createRenderer(options) {
  const { createElement, setElementText, insert } = options;
  function render(vnode, container) {
    console.log("container==", container);
    if (vnode) {
      patch(container._vnode, vnode, container);
    } else {
      if (container._vnode) {
        container.innerHTML = "";
      }
    }
    container._vnode = vnode;
    console.log("container==", container);
  }
  function patch(n1, n2, container) {
    if (!n1) {
      // n1不存在 仅挂载
      mountElement(n2, container);
    } else {
      // n1存在意味着打补丁
    }
  }
  function mountElement(vnode, container) {
    const el = createElement(vnode.type);
    if (typeof vnode.children === "string") {
      setElementText(el, vnode.children);
    }
    insert(el, container);
  }

  return {
    render,
  };
}
// 非浏览器API 调用自定义渲染器
const renderer2 = createRenderer({
  createElement(tag) {
    console.log(`创建元素 ${tag}`);
    return { tag };
  },
  setElementText(el, text) {
    console.log(`设置 ${JSON.stringify(el)} 的文本内容：${text}`);
    el.textContent = text;
  },
  insert(el, parent, anchor = null) {
    console.log(`将 ${JSON.stringify(el)} 添加到${JSON.stringify(parent)} 下`);
    parent.children = el;
  },
});
const container = {
  type: "root",
};
renderer2.render(vnode, container);
